package com.tul.vapp.servicecenter.service.impl;

import com.tul.cusa.common.util.DateUtil;
import com.tul.cusa.common.util.ListUtil;
import com.tul.cusa.common.util.StringUtil;
import com.tul.vapp.servicecenter.dao.IItemDao;
import com.tul.vapp.servicecenter.dao.INamespaceDao;
import com.tul.vapp.servicecenter.dao.IReleaseItemDao;
import com.tul.vapp.servicecenter.dao.IReleaseNamespaceDao;
import com.tul.vapp.servicecenter.entity.Namespace;
import com.tul.vapp.servicecenter.entity.Status;
import com.tul.vapp.servicecenter.service.INamespaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 操作数据库中的Namespace
 *
 * @author wwxiang
 * @since 2018/1/4.
 */
@Service
public class NamespaceService implements INamespaceService {

    @Autowired
    private INamespaceDao namespaceDao;

    @Autowired
    private IReleaseNamespaceDao releaseNamespaceDao;

    @Autowired
    private IItemDao itemDao;
    @Autowired
    private IReleaseItemDao releaseItemDao;

    @Override
    public boolean addNamespace(Namespace namespace) {
        namespaceDao.addNamespace(namespace);
        return true;
    }

    @Override
    public boolean updateNamespace(Namespace namespace) {
        namespaceDao.updateNamespace(namespace);
        return true;
    }

    @Override
    public List<Namespace> getNamespaces(String appId) {
        if (StringUtil.isEmpty(appId)) {
            throw new IllegalArgumentException("AppId can't be empty.");
        }
        return namespaceDao.getNamespaces(appId);
    }

    @Override
    public List<Namespace> getReleaseNamespaces(String appId) {
        if (StringUtil.isEmpty(appId)) {
            throw new IllegalArgumentException("AppId can't be empty.");
        }
        return releaseNamespaceDao.getNamespaces(appId);
    }

    @Override
    public List<Namespace> getNamespaces() {
        return namespaceDao.getAllNamespaces();
    }

    @Override
    public Namespace getNamespace(String appId, String namespace) {
        if (StringUtil.isEmpty(appId)) {
            throw new IllegalArgumentException("AppId can't be empty.");
        }
        if (StringUtil.isEmpty(namespace)) {
            throw new IllegalArgumentException("Namespace can't be empty.");
        }
        return namespaceDao.getNamespace(appId, namespace);
    }

    @Override
    public void deleteCascade(String appId, String namespace) {
        releaseNamespaceDao.deleteNamespace(appId, namespace);
        releaseItemDao.deleteItemInNs(appId, namespace);
        namespaceDao.deleteNamespace(appId, namespace);
        itemDao.deleteItemInNs(appId, namespace);
    }

    /**
     * 将数据更改到发布状态
     *
     * @param appId     应用id
     * @param namespace 命名空间
     */
    @Override
    public void publish(String appId, String namespace) {
        Namespace ns = namespaceDao.getNamespace(appId, namespace);
        ns.setUpdateTime(DateUtil.format(new Date(), DateUtil.DATE_TIME_FORMAT));
        if (ns.getStatus() == Status.DELETE) {
            // 已标记删除的，直接删除
            namespaceDao.deleteNamespace(appId, namespace);
            releaseNamespaceDao.deleteNamespace(appId, namespace);
        } else if (ns.getStatus() == Status.INSERT) {
            // 标记为新增的，只需要将状态更新为PUBLISHED
            ns.setStatus(Status.PUBLISHED);
            namespaceDao.updateNamespace(ns);
            releaseNamespaceDao.addNamespace(ns);
        } else if (ns.getStatus() == Status.MODIFY) {
            // 标记为修改的，将undo字段置为空,状态改为PUBLISHED
            ns.setStatus(Status.PUBLISHED);
            namespaceDao.updateNamespace(ns);

            // release表中已存在则更新，否则新增
            Namespace release = releaseNamespaceDao.getNamespace(appId, namespace);
            if (release != null) {
                releaseNamespaceDao.updateNamespace(ns);
            } else {
                releaseNamespaceDao.addNamespace(ns);
            }

        }
    }

    @Override
    public void rollback(String appId, String namespace) {
        Namespace ns = namespaceDao.getNamespace(appId, namespace);
        if (ns.getStatus() == Status.DELETE) {
            // 标记为删除的，只需要将状态回退到published
            ns.setStatus(Status.PUBLISHED);
            namespaceDao.updateNamespace(ns);
        } else if (ns.getStatus() == Status.INSERT) {
            // 标记为新增的，回退时，将此数据删除
            namespaceDao.deleteNamespace(ns.getAppId(), ns.getNamespace());
        } else if (ns.getStatus() == Status.MODIFY) {
            // 标记为修改的，根据release表进行回退
            Namespace release = releaseNamespaceDao.getNamespace(appId, namespace);
            namespaceDao.updateNamespace(release);
        }
    }

    @Override
    public void sanityCheck(String appId) {

        // 已发布的数据
        List<Namespace> nsReleaseObj = releaseNamespaceDao.getNamespaces(appId);
        List<String> nsRelease = new ArrayList();
        for (Namespace ns : nsReleaseObj) {
            nsRelease.add(ns.getNamespace());
        }

        // 操作表内的数据
        List<Namespace> nsObj = namespaceDao.getNamespaces(appId);
        List<String> nsDb = new ArrayList();
        for (Namespace ns : nsObj) {
            nsDb.add(ns.getNamespace());
        }

        // 发布表比操作表里多，是需要处理的
        List<String> adds = ListUtil.subtract(nsRelease, nsDb);
        for (String add : adds) {
            Namespace n = releaseNamespaceDao.getNamespace(appId, add);
            namespaceDao.addNamespace(n);
        }
    }
}
